package com.sh.data.engine.web.webapi.controller.datadev;

import com.sh.data.engine.application.model.dto.datadev.OfflineDevCreateTableResponse;
import com.sh.data.engine.application.model.dto.datadev.OfflineDevPreviewDataResponse;
import com.sh.data.engine.application.model.dto.datadev.OfflineDevSyncResponse;
import com.sh.data.engine.application.model.dto.integration.OfflineSyncDatabaseResponse;
import com.sh.data.engine.application.model.dto.integration.OfflineSyncTablesResponse;
import com.sh.data.engine.application.model.dto.integration.OfflineTaskExistTableMappingResponse;
import com.sh.data.engine.application.model.request.datadev.OfflineDevSyncRequest;
import com.sh.data.engine.application.model.request.integration.OfflineTaskExistTableMappingRequest;
import com.sh.data.engine.application.service.datadev.OfflineDevSyncApplicationService;
import com.sh.data.engine.common.enumDefinition.ProjectStatisticTypeEnum;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.ProjectStatisticExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@Validated
@RestController
@RequestMapping("/offlineDev/sync")
@Tag(name = "数据开发-离线开发-同步任务", description = "离线开发相关-同步任务API")
@Slf4j
public class OfflineDevSyncController {

    @Autowired
    private OfflineDevSyncApplicationService offlineDevSyncApplicationService;

    @Operation(summary = "保存/编辑任务", description = "保存/编辑任务")
//    @ApiImplicitParams({
//        @ApiImplicitParam(
//            paramType = "header",
//            dataType = "String",
//            name = Constants.HEADER_PROJECT_ID,
//            value = "项目id标识",
//            required = true),
//    })
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.离线同步任务)
//    @Log(
//        business = Business.离线同步任务,
//        operation = Operation.ADD_UPDATE)
    @PostMapping(value = "/save")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 1)
    public RestResponseEntity<Boolean> saveOfflineSyncTask(
        @Valid @RequestBody OfflineDevSyncRequest request) {
        var result = offlineDevSyncApplicationService.saveOfflineSyncTask(request);
        return RestResponseEntity.success(result);
    }

    @GetMapping(value = "/get")
    @Operation(summary = "获取任务信息", description = "获取任务信息")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<OfflineDevSyncResponse> getOfflineSyncTask(Long nodeId) {
        var result = offlineDevSyncApplicationService.getOfflineSyncTask(nodeId);
        return RestResponseEntity.success(result);
    }

    @GetMapping(value = "/previewData")
    @Operation(summary = "预览数据", description = "预览数据")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<OfflineDevPreviewDataResponse> previewData(
        @Parameter(description = "数据源id") @RequestParam(value = "dsId") Long dsId,
        @Parameter(description = "表名") @RequestParam(value = "tableName") String tableName) {
        var result = offlineDevSyncApplicationService.previewData(dsId, tableName);
        return RestResponseEntity.success(result);
    }

    @GetMapping(value = "/getCreateTableSql")
    @Operation(summary = "获取建表语句", description = "获取建表语句")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<String> getCreateTableSql(
        @Parameter(description = "数据源id") @RequestParam(value = "dsId") Long dsId,
        @Parameter(description = "数据表名称") @RequestParam(value = "tableName") String tableName,
        @Parameter(description = "目标数据库ID") @RequestParam(value = "targetDsId") Long targetDsId,
        @Parameter(description = "schema") @RequestParam(value = "schema") String schema,
        @Parameter(description = "infoCase")
        @RequestParam(value = "infoCase", required = false, defaultValue = "1")
        int infoCase) {
        var result = offlineDevSyncApplicationService.getCreateTableSql(dsId, tableName, targetDsId, schema, infoCase);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "执行一键建表语句", description = "执行一键建表语句")
//    @ApiImplicitParams({
//        @ApiImplicitParam(
//            paramType = "header",
//            dataType = "String",
//            name = Constants.HEADER_PROJECT_ID,
//            value = "项目id标识",
//            required = true),
//    })
    @LogExecution(operation = EngineOperation.DATA_SYNC_CREATE_TABLE, business = Business.离线同步任务)
//    @Log(
//        business = Business.离线同步任务,
//        operation = Operation.DATA_SYNC_CREATE_TABLE)
    @PostMapping(value = "/executeCreateTableSql")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.TABLE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 1)
    public RestResponseEntity<OfflineDevCreateTableResponse> executeCreateTableSql(
        @Parameter(description = "数据源id") @RequestParam(value = "dsId") Long dsId,
        @Parameter(description = "SQL脚本", required = true) @RequestParam(value = "scripts") String scripts,
        @Parameter(description = "密级", required = false) @RequestParam(value = "dataSecretId") String dataSecretId) {
        var result = offlineDevSyncApplicationService.executeCreateTableSql(dsId, scripts, dataSecretId);
        return RestResponseEntity.success(result);
    }

    @GetMapping("/databases")
    @Operation(summary = "获取数据源信息", description = "获取数据源信息")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<List<OfflineSyncDatabaseResponse>> getOfflineSyncDatabases(
        @Parameter(description = "数据源来源 0-来源 1-目标", required = true) @RequestParam(value = "direction")
        Integer direction,
        @Parameter(description = "来源数据源id") @RequestParam(value = "dsId", required = false) String dsId) {
        var result = offlineDevSyncApplicationService.getOfflineSyncDatabases(dsId, direction);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "查询所有表", description = "查询所有表")
    @GetMapping("/tables")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<List<OfflineSyncTablesResponse>> getTables(
        @Parameter(description = "数据源id") @RequestParam(value = "dsId") Long dsId,
        @Parameter(description = "schema") @RequestParam(value = "schema", required = false) String schema,
        @Parameter(description = "数据源来源 0-来源 1-目标", required = true) @RequestParam(value = "direction")
        Integer direction) {
        var result = offlineDevSyncApplicationService.getTables(dsId, schema, direction);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "查询数据库下所有schema", description = "查询数据库下所有schema")
    @GetMapping("/schema")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<List<String>> getSchemas(
        @Parameter(description = "数据源id") @RequestParam(value = "dsId") Long dsId,
        @Parameter(description = "数据源类型", required = true) @RequestParam(value = "dsType") String dsType) {
        var result = offlineDevSyncApplicationService.getSchemas(dsId, dsType);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "表和字段映射(已存在)", description = "表和字段映射(已存在)")
//    @ApiImplicitParams({
//        @ApiImplicitParam(
//            paramType = "header",
//            dataType = "String",
//            name = Constants.HEADER_PROJECT_ID,
//            value = "项目id标识",
//            required = true),
//    })
    @PostMapping("/table/fields")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<OfflineTaskExistTableMappingResponse> getExistTablesMappings(
        @RequestBody OfflineTaskExistTableMappingRequest request) {
        var result = offlineDevSyncApplicationService.getExistTablesMappings(request);
        return RestResponseEntity.success(result);
    }

    @GetMapping("/sapTableExit")
    @Operation(summary = "判断SAP表是否存在", description = "判断SAP表是否存在")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 0)
    public RestResponseEntity<Boolean> sapTableExit(
        @Parameter(description = "数据源id") @RequestParam(required = true) Long dsId,
        @Parameter(description = "数据表名称") @RequestParam(required = true) @NotBlank String tableName) {
        var result = offlineDevSyncApplicationService.sapTableExist(dsId, tableName);
        return RestResponseEntity.success(result);
    }

    @GetMapping("/start")
    @Operation(summary = "启动离线同步任务", description = "启动离线同步任务")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZYKF, readWriteStatus = 1)
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.离线同步任务)
//    @Log(
//        business = Business.离线同步任务,
//        operation = Operation.START_TASK)
    public RestResponseEntity<Long> startOfflineSyncTask(
        @Parameter(description = "nodeId") @RequestParam(value = "nodeId") Long nodeId) {
        var result = offlineDevSyncApplicationService.startOfflineSyncTask(nodeId);
        return RestResponseEntity.success(result);
    }
}
